﻿#region Header
// ------------------------ Licence / Copyright ------------------------
// 
// ScrumTable for Scrum Meeting Support
// Copyright © HSR - Hochschule für Technik Rapperswil
// All Rights Reserved
// 
// Author:
//  Michael Gfeller Silvan Gehrig Patrick Boos
// 
// ---------------------------------------------------------------------
#endregion

namespace ScrumTable.Common
{
    #region Usings

    using System;
    using System.Text;
    using System.Collections;

    #endregion

    /// <summary>
    /// Contains the global utilities for the Exception class.
    /// </summary>
    public static class ExceptionUtil
    {
        #region Methods

        //--------------------------------------------------------------------
        // Methods
        //--------------------------------------------------------------------

        /// <summary>
        /// Extracts an error string with all information of an exception.
        /// </summary>
        /// <param name="input">Input pointer from extension method.</param>
        /// <returns>Returns the generaed string.</returns>
        public static string ToFullErrorString(this Exception input)
        {
            PreCondition.AssertNotNull(input, "input");

            StringBuilder errorBuilder = new StringBuilder();
            Exception current = input;
            bool first = true;

            while (current != null)
            {
                if (!first)
                {
                    errorBuilder.AppendLine("--- inner exception ---");
                }

                errorBuilder.Append(current.Message);
                errorBuilder.Append(" [");
                errorBuilder.Append(current.GetType().FullName);
                errorBuilder.AppendLine("]");

                if (current.StackTrace != null)
                {
                    errorBuilder.AppendLine(current.StackTrace);
                }

                errorBuilder.Append("HelpLink: ");
                errorBuilder.AppendLine(current.HelpLink);
                errorBuilder.Append("Source: ");
                errorBuilder.AppendLine(current.Source);
                errorBuilder.Append("Data: ");


                if (current.Data != null)
                {
                    foreach (DictionaryEntry data in current.Data)
                    {
                        errorBuilder.Append(" ");
                        errorBuilder.Append(data.Key);
                        errorBuilder.Append(" [");
                        errorBuilder.Append(data.Key.GetType().FullName);
                        errorBuilder.Append("]");

                        if (data.Value != null)
                        {
                            errorBuilder.Append(" => ");
                            errorBuilder.Append(data.Value);
                            errorBuilder.Append(" [");
                            errorBuilder.Append(data.Key.GetType().FullName);
                            errorBuilder.Append("]");
                        }
                        errorBuilder.AppendLine();
                    }
                }
                
                current = current.InnerException;
                first = false;
            }
            return errorBuilder.ToString();
        }

        /// <summary>
        /// Extracts an error string with all messages of an exception.
        /// </summary>
        /// <param name="input">Input pointer from extension method.</param>
        /// <returns>Returns the generaed string.</returns>
        public static string ToMessageErrorString(this Exception input)
        {
            PreCondition.AssertNotNull(input, "input");

            string errorString = string.Empty;
            Exception current = input;

            while (current != null)
            {
                // make sure message is well terminated
                string message = current.Message;

                if (!message.EndsWith("."))
                {
                    message += ".";
                }

                // make sure parent exception does not contain the message
                // of the inner exception
                if (!errorString.EndsWith(message))
                {
                    if (errorString.Length != 0)
                    {
                        errorString += " " + Environment.NewLine;
                    }

                    errorString += message;
                }
                current = current.InnerException;
            }
            return errorString;
        }

        #endregion
    }
}
